<template>
  <div class="ExpenseType-container">
    <div class="tree-wrap">
      <v-skeleton-loader
        v-if="loading"
        height="100%"
        type="list-item@20"
      ></v-skeleton-loader>
      <Tree
        v-else
        :items="items"
        @add="openAddDialog(false, undefined)"
        addTooltip="Add Expense Type"
        hoverable
        expand-icon="mdi-chevron-down"
      >
        <template #title>
          <span class="ml-4"> Expense Type > Expense Remarks </span>
        </template>
        <template #label="{ item }">
          {{ item.expenseType }}
          {{ item.expenseRemarks }}
          <span class="ml-1" v-if="item.shortName">({{ item.shortName }})</span>
        </template>
        <template #append="{ item }">
          <div @click.stop class="action">
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  v-if="!!item.expenseType"
                  @click="openAddDialog(true, item)"
                  v-bind="attrs"
                  v-on="on"
                  small
                  class="mr-2 pointer"
                  color="#79839B"
                >
                  mdi-plus
                </v-icon>
              </template>
              <span>Add Expense Remarks</span>
            </v-tooltip>
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  @click="openEditDialog(!item.expenseType, item)"
                  v-bind="attrs"
                  v-on="on"
                  small
                  class="mr-2 pointer"
                  color="#79839B"
                >
                  mdi-square-edit-outline
                </v-icon>
              </template>
              <span
                >Edie Expense {{ !item.expenseType ? "Remarks" : "Type" }}</span
              >
            </v-tooltip>
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  @click="openDeleteDialog(!item.expenseType, item)"
                  v-bind="attrs"
                  v-on="on"
                  small
                  color="#79839B"
                >
                  mdi-delete
                </v-icon>
              </template>
              <span
                >Delete Expense
                {{ !item.expenseType ? "Remarks" : "Type" }}</span
              >
            </v-tooltip>
          </div>
        </template>
      </Tree>
    </div>
    <Dialog
      v-model="showDialog"
      @submit="save"
      :title="dialogTitle"
      :show-save="step <= 4"
      width="480"
    >
      <AddEditExpenseType
        v-if="[1, 2].includes(step)"
        ref="addEditExpenseType"
      ></AddEditExpenseType>
      <AddEditExpenseRemarks
        v-else-if="[3, 4].includes(step)"
        ref="addEditExpenseRemarks"
      ></AddEditExpenseRemarks>
      <DeleteExpenseType
        v-else-if="step === 5"
        ref="deleteExpenseType"
        @delete="deleteExpenseType"
        :item="selectedExpenseType"
      ></DeleteExpenseType>
      <DeleteExpenseRemarks
        v-else-if="step === 6"
        ref="deleteExpenseRemarks"
        @delete="deleteExpenseRemarks"
        :item="selectedExpenseRemarks"
      ></DeleteExpenseRemarks>
    </Dialog>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import Tree from "@/components/Maintenance/Tree/Tree.vue";
import Dialog from "@/components/Maintenance/Dialog/Dialog.vue";
import AddEditExpenseRemarks from "@/components/Maintenance/Setting/ExpenseType/AddEditExpenseRemarks.vue";
import AddEditExpenseType from "@/components/Maintenance/Setting/ExpenseType/AddEditExpenseType.vue";
import DeleteExpenseRemarks from "@/components/Maintenance/Setting/ExpenseType/DeleteExpenseRemarks.vue";
import DeleteExpenseType from "@/components/Maintenance/Setting/ExpenseType/DeleteExpenseType.vue";
interface IExpenseType {
  id: string;
  expenseType: string;
  shortName: string;
  code: string;
  children: IExpenseRemarks[];
}
interface IExpenseRemarks {
  id: string;
  expenseRemarks: string;
}
@Component({
  components: {
    Tree,
    Dialog,
    AddEditExpenseRemarks,
    AddEditExpenseType,
    DeleteExpenseRemarks,
    DeleteExpenseType,
  },
})
export default class ExpenseType extends Vue {
  loading = false;
  // 1.AddExpenseType 2.EditExpenseType 3.AddExpenseRemarks 4.EditExpenseRemarks 5.DeleteExpenseType 6.DeleteExpenseRemarks
  step = -1;
  // Dialog
  showDialog = false;
  dialogTitle = "";
  openDialog() {
    this.showDialog = true;
  }
  closeDialog() {
    this.showDialog = false;
  }
  // Tree
  selectedExpenseType: IExpenseType | null = null;
  selectedExpenseRemarks: IExpenseRemarks | null = null;
  items: IExpenseType[] = [];
  getItems() {
    this.loading = true;
    setTimeout(() => {
      this.items = [
        {
          id: "1",
          expenseType: "Meal Allowance",
          shortName: "MEAL",
          code: "QA",
          children: [
            {
              id: "2",
              expenseRemarks: "OT Meal",
            },
          ],
        },
        {
          id: "3",
          expenseType: "Other Expense",
          shortName: "OTH",
          code: "ES",
          children: [
            {
              id: "4",
              expenseRemarks: "Internal Use",
            },
            {
              id: "5",
              expenseRemarks: "On Site Support",
            },
          ],
        },
        {
          id: "6",
          expenseType: "Transportation",
          shortName: "TRANS",
          code: "TA",
          children: [
            {
              id: "7",
              expenseRemarks: "On site Support",
            },
            {
              id: "8",
              expenseRemarks: "Regular Expense",
            },
          ],
        },
      ];
      this.loading = false;
    }, 400);
  }
  // Action
  openAddDialog(lime: boolean, item: IExpenseType | undefined) {
    if (lime && item) {
      this.step = 3;
      this.dialogTitle = "Add Expense Remarks";
      this.selectedExpenseType = item;
      this.$nextTick(() => {
        const addEditExpenseRemarksRef = this.$refs
          .addEditExpenseRemarks as AddEditExpenseRemarks;
        addEditExpenseRemarksRef.resetForm();
        setTimeout(() => {
          addEditExpenseRemarksRef.setFormData({
            expenseType: item.expenseType,
          });
        });
      });
    } else {
      this.step = 1;
      this.dialogTitle = "Add Expense Type";
      this.$nextTick(() => {
        (this.$refs.addEditExpenseType as AddEditExpenseType).resetForm();
      });
    }
    this.openDialog();
  }
  openEditDialog(leaf: boolean, item: IExpenseType | IExpenseRemarks) {
    if (leaf) {
      const expenseRemarks = item as IExpenseRemarks;
      const parent = this.getParent(this.items, expenseRemarks);
      this.step = 4;
      this.dialogTitle = "Edit Expense Remarks";
      this.selectedExpenseRemarks = expenseRemarks;
      this.$nextTick(() => {
        const addEditExpenseRemarksRef = this.$refs
          .addEditExpenseRemarks as AddEditExpenseRemarks;
        addEditExpenseRemarksRef.resetForm();
        setTimeout(() => {
          addEditExpenseRemarksRef.setFormData({
            expenseType: parent.expenseType,
            ...expenseRemarks,
          });
        });
      });
    } else {
      this.step = 2;
      this.dialogTitle = "Edit Expense Type";
      this.selectedExpenseType = item as IExpenseType;
      this.$nextTick(() => {
        const addEditExpenseTypeRef = this.$refs
          .addEditExpenseType as AddEditExpenseType;
        addEditExpenseTypeRef.resetForm();
        setTimeout(() => {
          addEditExpenseTypeRef.setFormData(item);
        });
      });
    }
    this.openDialog();
  }
  openDeleteDialog(leaf: boolean, item: IExpenseType | IExpenseRemarks) {
    if (leaf) {
      this.step = 6;
      this.dialogTitle = "Delete Expense Remarks";
      this.selectedExpenseRemarks = item as IExpenseRemarks;
    } else {
      this.step = 5;
      this.dialogTitle = "Delete Expense Type";
      this.selectedExpenseType = item as IExpenseType;
    }
    this.openDialog();
  }
  // 1.AddExpenseType 2.EditExpenseType 3.AddExpenseRemarks 4.EditExpenseRemarks 5.DeleteExpenseType 6.DeleteExpenseRemarks
  async save() {
    let addEditRef: AddEditExpenseType | AddEditExpenseRemarks | null = null;
    if ([1, 2].includes(this.step)) {
      addEditRef = this.$refs.addEditExpenseType as AddEditExpenseType;
    } else if ([3, 4].includes(this.step)) {
      addEditRef = this.$refs.addEditExpenseRemarks as AddEditExpenseRemarks;
    }
    if (addEditRef) {
      const result = await addEditRef.validateFormData();
      console.log(result);
      if (result) {
        // 1.addExpenseType 3.addExpenseRemarks
        if ([1, 3].includes(this.step)) {
          result.id = String(new Date().getTime());
          if (this.step === 1) {
            this.addExpenseType(result as IExpenseType);
          } else {
            const expenseRemarks = {
              id: result.id,
              expenseRemarks: (result as IExpenseRemarks).expenseRemarks,
            };
            this.addExpenseRemarks(
              this.selectedExpenseType as IExpenseType,
              expenseRemarks
            );
          }
        } else if ([2, 4].includes(this.step)) {
          // 2.editExpenseType 4.editExpenseRemarks
          if (this.step === 2) {
            this.edit(
              this.selectedExpenseType as IExpenseType,
              result as IExpenseType
            );
          } else {
            const expenseRemarks = {
              id: result.id,
              expenseRemarks: (result as IExpenseRemarks).expenseRemarks,
            };
            this.edit(
              this.selectedExpenseRemarks as IExpenseRemarks,
              expenseRemarks as IExpenseRemarks
            );
          }
        }
        this.closeDialog();
      }
    }
  }

  addExpenseType(item: IExpenseType) {
    this.items.push(item);
  }

  addExpenseRemarks(parent: IExpenseType, item: IExpenseRemarks) {
    if (parent.children) {
      parent.children.push(item);
    } else {
      this.$set(parent, "children", [item]);
    }
  }

  edit<T extends IExpenseType | IExpenseRemarks>(itemCate: T, item: T) {
    Object.assign(itemCate, item);
  }

  deleteExpenseType(item: IExpenseType) {
    const index = this.items.indexOf(item);
    this.items.splice(index, 1);
    this.closeDialog();
  }

  deleteExpenseRemarks(item: IExpenseRemarks) {
    const parent = this.getParent(this.items, item);
    const index = parent.children.indexOf(item);
    parent.children.splice(index, 1);
    this.closeDialog();
  }

  // 获取父级元素
  getParent(items: IExpenseType[], child: IExpenseRemarks): IExpenseType {
    return items.filter((treeItem) => {
      return treeItem.children.includes(child);
    })[0];
  }

  created() {
    this.getItems();
  }

  mounted() {
    this.$store.commit("MaintenanceStore/switchActionIcon", "mdi-file-export");
  }
}
</script>

<style lang="scss" scoped>
@import "./ExpenseType.scss";
</style>
